#include <bits/stdc++.h>
using namespace std;

// 状态类型：边界 + 高桥相对的地图偏移量
typedef tuple<int, int, int, int, int, int> STATUS;

vector<string> grid;

map<STATUS, int> dist;

queue<STATUS> q;

int H, W, Si, Sj;

void pushState(int up, int down, int lef, int rig, int offset_i, int offset_j,
               int step) {
  // 更新边界：基于当前状态的垃圾区域的偏移量
  up = max(up, 0 + offset_i);
  down = min(down, H + offset_i);
  lef = max(lef, 0 + offset_j);
  rig = min(rig, W + offset_j);

  // 检查高桥位置是否在有效区域内且不是障碍物
  int ti = Si + offset_i;
  int tj = Sj + offset_j;

  if (up <= ti && ti < down && lef <= tj && tj < rig) {
    if (grid[ti][tj] == '#')
      return;
  }

  STATUS st(up, down, lef, rig, offset_i, offset_j);
  if (dist.find(st) != dist.end())
    return;

  dist[st] = step;
  q.emplace(st);
}

int main() {
  cin >> H >> W;
  grid.resize(H);
  for (int i = 0; i < H; ++i)
    cin >> grid[i];

  // 找到高桥位置
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (grid[i][j] == 'T') {
        Si = i;
        Sj = j;
        break;
      }
    }
  }

  // 初始状态：整个网格，垃圾区域偏移量为 (0, 0)
  pushState(0, H, 0, W, 0, 0, 0);

  while (!q.empty()) {
    STATUS curr = q.front();
    int step = dist[curr];
    q.pop();

    auto [up, down, lef, rig, offset_i, offset_j] = curr;

    // 检查当前区域内是否没有障碍物
    int cnt = 0;
    for (int i = up; i < down; ++i) {
      for (int j = lef; j < rig; ++j) {
        if (grid[i][j] == '#')
          cnt++;
      }
    }
    if (cnt == 0) {
      cout << step << '\n';
      return 0;
    }

    // 向四个方向移动垃圾区域（改变偏移量）
    pushState(up, down, lef, rig, offset_i - 1, offset_j,
              step + 1); // 向下移动垃圾，高桥相对向上移动
    pushState(up, down, lef, rig, offset_i + 1, offset_j,
              step + 1); // 向上移动垃圾
    pushState(up, down, lef, rig, offset_i, offset_j - 1,
              step + 1); //
    pushState(up, down, lef, rig, offset_i, offset_j + 1, step + 1);
  }

  cout << -1 << endl;
  return 0;
}